package com.nanbei.list;

import java.util.Arrays;
import java.util.Iterator;
import java.util.function.Consumer;
import java.util.stream.IntStream;

/**
 * 动态数组
 */
public class DynamicArray implements Iterable<Integer> {

    private int size = 0; // 逻辑大小
    private int capacity = 8; // 容量
    private int[] array = {};

    /**
     * 向数组的最后一位添加数据
     *
     * @param num 最后一位添加的数据
     */
    public void addLast(int num) {
        add(size,num);
    }

    /**
     * 向数组中的某个位置添加元素
     *
     * @param index 要添加元素的下标
     * @param num   要添加元素的数据
     */
    public void add(int index, int num) {

        checkAndGrow();

        // 判断是否小于size 小于size是在中间插入 等于size是在末尾插入此时并不需要进行数组拷贝
        if (index >= 0 && index < size) {
            System.arraycopy(array, index, array, index + 1, size - index);
        }
        array[index] = num;
        size++;
    }

    /**
     * 检测数组长度是否需要扩容
     */
    private void checkAndGrow() {
        if (size == 0){
            array = new int[capacity];
        } else if (size==capacity){
            capacity += capacity >> 1;
            int[] newArray = new int[capacity];
            System.arraycopy(array,0,newArray,0,size);
            array = newArray;
        }
    }

    /**
     * 根据index下标删除该位置的元素
     *
     * @param index 要删除元素的下标
     * @return 返回删除的元素
     */
    public int delByIndex(int index) {

        int num = array[index];
        System.arraycopy(array, index + 1, array, index, size - index - 1);
        size--;
        return num;
    }

    /**
     * 根据下标获取下标的数据
     *
     * @param index 下标
     * @return 下标所对应的数据
     */
    public int get(int index) {
        return array[index];
    }

    /**
     * 遍历数组元素，将每个元素返回回去
     *
     * @param consumer 函数式接口（接收一个参数，返回一个参数）
     */
    public void foreachUp(Consumer<Integer> consumer) {
        for (int i = 0; i < size; i++) {
            consumer.accept(array[i]);
        }
    }


    /**
     * 迭代器遍历
     *
     * @return 返回数据元素
     */
    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {

            int i = 0;

            @Override
            public boolean hasNext() {
                return i < size;  //是否含有下个元素 不能加=
            }

            @Override
            public Integer next() {
                return array[i++];
            }
        };
    }

    /**
     * 使用stream流的方式进行遍历
     *
     * @return intStream
     */
    public IntStream stream() {
        return IntStream.of(Arrays.copyOfRange(array, 0, size));
    }
}
